<?php
/**
 * Description of SQMCDimClass
 *
 * Sub Question Image File Check
 *
 * @author Chisheng Lu
 * @copyright DoRISE team, Science Education center, NTNU.
 * @since 2010-03-11
 * @version 1.0
 */
class UploadImage {
    private $mysqli;
    private $max_width;
    private $max_height;
    private $thumb_width;
    private $thumb_height;
    private $rsStrImagePic = null;
    private $rsDestImagePic = null;
    private $rsThumbImage = null;

    function __construct() {
        ini_set('memory_limit', '100M');
        $this->max_width = 500;
        $this->max_height = 500;
        $this->thumb_width = 100;
        $this->thumb_height = 100;

        //引入資料庫連結參數設定
        include '../inc/oaConn.inc.php';
        $this->mysqli = @new mysqli($mysqlHost,$mysqlUser,$mysqlPassword,$mysqlDB);
        if(mysqli_connect_errno()) {
            throw new Exception('無法建立資料庫連線！'.mysqli_connect_error());
            $this->mysqli = false;
            exit();
        }

        //連線使用編碼
        $this->mysqli->query("SET NAMES 'utf8'");

        //引入設定檔
        include_once('../inc/setup.inc.php');
    }

    /**
     *
     * @param String $strSrcFileName 原始圖檔案路徑與檔名
     * @param String $strDestFileName
     * @param String $strFileType 圖檔型別
     * @return <type>
     */
    public function saveUploadImageToFile($strSrcFileName, $strDestFileName, $strFileType) {
        $bolRtn = false;

        //取得
        $intLength = strlen($strDestFileName);
        $intLocation = strrpos($strDestFileName,'/') + 1;
        $strFileName = substr($strDestFileName, $intLocation, ($intLength-$intLocation));
        $strDestFilePath = substr($strDestFileName, 0, $intLocation);
        $strThumbFile = $strDestFilePath . 'thumb/' . $strFileName;

        try {
            //將上傳圖片讀入記憶體中
            $this->rsStrImagePic = $this->loadImageToMemory($strSrcFileName, $strFileType);
        } catch (Exception $e) {
            throw new Exception($e);
        }
        //取得圖片的原始寬度、高度
        $aryImgSize = getimagesize($strSrcFileName);
        if (!$aryImgSize) {
            throw new Exception('讀取圖檔長寬點數錯誤！');
        }
        list($width,$height) = $aryImgSize;

        //判斷上傳圖檔常寬大小及適度新圖的長寬
        $x_ratio = $this->max_width / $width;
        $y_ratio = $this->max_height / $height;

        if ( ($width <= $this->max_width) && ($height <= $this->max_height) ) {
            $tn_width = $width;
            $tn_height = $height;
        }elseif(($x_ratio * $height) < $this->max_height) {
            $tn_height = ceil($x_ratio * $height);
            $tn_width = $this->max_width;
        }else {
            $tn_width = ceil($y_ratio * $width);
            $tn_height = $this->max_height;
        }

        //判斷上傳圖檔常寬大小及適度縮小為縮圖大小
        $x_ratio = $this->thumb_width / $width;
        $y_ratio = $this->thumb_height / $height;

        if( ($width <= $this->thumb_width) && ($height <= $this->thumb_height) ) {
            $thumb_width = $width;
            $thumb_height = $height;
        }elseif(($x_ratio * $height) < $this->thumb_height) {
            $thumb_height = ceil($x_ratio * $height);
            $thumb_width = $this->thumb_width;
        }else {
            $thumb_width = ceil($y_ratio * $width);
            $thumb_height = $this->thumb_height;
        }

        //在記憶體中建立新圖
        $this->rsDestImagePic = imagecreatetruecolor($tn_width,$tn_height);
        if (!$this->rsDestImagePic) {
            throw new Exception('建立新圖錯誤！');
        }
        //將原始圖片複製並縮小成為新的圖片
        $bolRtn = imagecopyresampled($this->rsDestImagePic,$this->rsStrImagePic,0,0,0,0,$tn_width, $tn_height,$width,$height);
        if (!$bolRtn) {
            throw new Exception('複製成新圖錯誤！');
        }

        //在記憶體中建立縮圖位置
        $this->rsThumbImage = imagecreatetruecolor($thumb_width,$thumb_height);
        if (!$this->rsThumbImage) {
            throw new Exception('建立縮圖新圖錯誤！');
        }
        //將原始圖片複製並縮小成為縮圖
        $bolThumbRtn = imagecopyresampled($this->rsThumbImage,$this->rsStrImagePic,0,0,0,0,$thumb_width, $thumb_height,$width,$height);
        if (!$bolThumbRtn) {
            throw new Exception('複製成新縮圖錯誤！');
        }

        //將新圖重新寫入目標路徑
        //imagejpeg($this->rsDestImagePic,$strDestFileName,100);
        try {
            $bolRtn = $this->saveThumbImage($this->rsDestImagePic,$strDestFileName,$strFileType);
            $bolThumbRtn = $this->saveThumbImage($this->rsThumbImage,$strThumbFile,$strFileType);
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }

        return $bolRtn;

    }

    public function addUploadRecordNoQId($intQType, $strFilePath='', $strCreateTime='') {

        $intRtn = 0;
        $sql_addUpload = 'INSERT INTO `UploadImage` (`QuestionType`, `FilePath`, `UICreateTime`)
            VALUES('. $intQType .', \''. $strFilePath .'\', \''. $strCreateTime .'\')';
        $rs_addUpload = $this->mysqli->query($sql_addUpload);
        if(!$rs_addUpload) {
            throw new Exception('上傳圖片寫入資料庫發生錯誤！');
        }else {
            $intRtn = $this->mysqli->insert_id;
        }

        return $intRtn;

    }

    /**
     *
     * @param String $strUIIds 要更改的上傳資料編號字串
     * @param Integer $intQId 題目編號
     * @return Boolen
     */
    public function setUploadedQId($strUIIds, $intQId) {
        $bolRtn = false;
        $sql_setQIds = 'UPDATE `UploadImage` SET `QId`=' . $intQId . ' WHERE `UIId` IN(' . $strUIIds . ')';
        $rs_setQIds = $this->mysqli->query($sql_setQIds);

        if(!$rs_setQIds) {
            throw new Exception('更新已上傳圖檔題目編號資料時發生錯誤！');
        }else {
            $bolRtn = true;
        }

        return $bolRtn;

    }

    public function getAllMQUploadImgByMQId($intMQId) {
        $aryGetAllImg = array();

        $sql_GetAllImg = 'SELECT * FROM `UploadImage` WHERE `QuestionType`=0 AND `QId`=' . $intMQId;
        $rs_GetAllImg = $this->mysqli->query($sql_GetAllImg);

        if(!$rs_GetAllImg) {
            throw new Exception('無法查詢附圖，查詢子題附圖發生錯誤！');
        }else {
            while ($row_GetAllImg = $rs_GetAllImg->fetch_row()) {
                array_push($aryGetAllImg, $row_GetAllImg);
            }
        }

        return $aryGetAllImg;
    }

    public function getAllSQUploadImgBySQId($intSQId) {
        $aryGetAllImg = array();

        $sql_GetAllImg = 'SELECT * FROM `UploadImage` WHERE `QuestionType`=1 AND `QId`=' . $intSQId;
        $rs_GetAllImg = $this->mysqli->query($sql_GetAllImg);

        if(!$rs_GetAllImg) {
            throw new Exception('無法查詢附圖，查詢子題附圖發生錯誤！');
        }else {
            while ($row_GetAllImg = $rs_GetAllImg->fetch_row()) {
                array_push($aryGetAllImg, $row_GetAllImg);
            }
        }

        return $aryGetAllImg;
    }

    private function saveThumbImage($rsDestImagePic, $strDestFileName, $strFileType) {
        switch ($strFileType) {
            case 'image/pjpeg':
                $bolRtn = imagejpeg($rsDestImagePic, $strDestFileName, 100);
                break;
            case 'image/jpeg':
                $bolRtn = imagejpeg($rsDestImagePic, $strDestFileName, 100);
                break;
            case 'image/gif':
                $bolRtn = imagegif($rsDestImagePic, $strDestFileName, 100);
                break;
            case 'image/x-png':
                $bolRtn = imagepng($rsDestImagePic, $strDestFileName);
                break;
            case 'image/png':
                $bolRtn = imagepng($rsDestImagePic, $strDestFileName);
                break;
            case 'image/bmp':
                $bolRtn = image2wbmp($rsDestImagePic, $strDestFileName);
                break;
            default:
                throw new Exception('圖檔類型不支援！');
                break;
        }
        if (!$bolRtn) {
            throw new Exception('儲存圖檔 ' + $strDestFileName + '.' . $strFileType . '  錯誤！');
        }
        return $bolRtn;
    }

    /**
     *
     * @param String $strFileName
     * @param String $strFileType
     * @return Object 記憶體裡的圖檔
     * @abstract 依照不同檔案型別，將原始圖片載入記憶體
     */
    private function loadImageToMemory($strFileName, $strFileType) {
        switch ($strFileType) {
            case 'image/pjpeg':
                $rsImagePic = imagecreatefromjpeg($strFileName);
                break;
            case 'image/jpeg':
                $rsImagePic = imagecreatefromjpeg($strFileName);
                break;
            case 'image/gif':
                $rsImagePic = imagecreatefromgif($strFileName);
                break;
            case 'image/x-png':
                $rsImagePic = imagecreatefrompng($strFileName);
                break;
            case 'image/png':
                $rsImagePic = imagecreatefrompng($strFileName);
                break;
            case 'image/bmp':
                $rsImagePic = $this->imagecreatefrombmp($strFileName);
                break;
            default:
                throw new Exception('圖檔類型不支援！');
                break;
        }
        if (!$rsImagePic) {
            throw new Exception('讀取圖檔 ' + $strFileName + '.' . $strFileType . '  錯誤！');
        }
        return $rsImagePic;
    }

    private function imagecreatefrombmp($filename) {
        $file = fopen( $filename, "rb" );
        $read = fread( $file, 10 );
        while( !feof( $file ) && $read != "" ) {
            $read .= fread( $file, 1024 );
        }
        $temp = unpack( "H*", $read );
        $hex = $temp[1];
        $header = substr( $hex, 0, 104 );
        $body = str_split( substr( $hex, 108 ), 6 );
        if( substr( $header, 0, 4 ) == "424d" ) {
            $header = substr( $header, 4 );
            // Remove some stuff?
            $header = substr( $header, 32 );
            // Get the width
            $width = hexdec( substr( $header, 0, 2 ) );
            // Remove some stuff?
            $header = substr( $header, 8 );
            // Get the height
            $height = hexdec( substr( $header, 0, 2 ) );
            unset( $header );
        }
        $x = 0;
        $y = 1;
        $image = imagecreatetruecolor( $width, $height );
        if (!$image) {
            throw new Exception('建立新圖錯誤！');
        }
        foreach( $body as $rgb ) {
            $r = hexdec( substr( $rgb, 4, 2 ) );
            $g = hexdec( substr( $rgb, 2, 2 ) );
            $b = hexdec( substr( $rgb, 0, 2 ) );
            $color = imagecolorallocate( $image, $r, $g, $b );
            if (!$color) {
                throw new Exception('分派圖色彩錯誤！');
            }
            $bolRtn = imagesetpixel( $image, $x, $height-$y, $color );
            if (!$bolRtn) {
                throw new Exception('畫一圖點錯誤！');
            }
            $x++;
            if( $x >= $width ) {
                $x = 0;
                $y++;
            }
        }
        return $image;
    }

    public function delUploadImageByULId($intULId) {
        $bolRtn = false;
        if(empty ($intULId)) {
            throw new Exception('缺少上傳記錄編號，無法刪除上傳圖檔。');
        }

        $sql_getFilename = 'SELECT `FilePath` FROM `UploadImage` WHERE `UIId`=' . $intULId;
        $rs_getFilename = $this->mysqli->query($sql_getFilename);
        if(!$rs_getFilename) {
            throw new Exception('查詢上傳圖檔名稱時發生錯誤。');
        }
        $row_getFilename = $rs_getFilename->fetch_row();
        $strFileName = $row_getFilename[0];

        $rs_getFilename->free_result();

        //刪除上傳原始圖檔
        $strOrigImg = _APP_PATH . "uploadfiles/" . $strFileName;
        if(file_exists($strOrigImg)) {
            if(!unlink($strOrigImg)){
                throw new Exception('刪除上傳原始圖檔失敗');
            }
        }

        //刪除重製圖檔
        $strRebuildImg = _APP_PATH . "uploadfiles/saved/" . $strFileName;
        if(file_exists($strRebuildImg)) {
            if(!unlink($strRebuildImg)){
                throw new Exception('刪除上傳的重製圖檔失敗');
            }
        }

        //刪除重製的縮圖
        $strThumbImg = _APP_PATH . "uploadfiles/saved/thumb/" . $strFileName;
        if(file_exists($strThumbImg)) {
            if(!unlink($strThumbImg)){
                throw new Exception('刪除上傳的重製縮圖失敗');
            }
        }

        //刪除
        $sql_delUI = 'DELETE FROM `UploadImage` WHERE `UIId`=' . $intULId;
        $rs_delUI = $this->mysqli->query($sql_delUI);
        if (!$rs_delUI) {
            throw new Exception('刪除上傳圖檔時發生錯誤。');
        }else {
            $bolRtn = true;
        }
        
        return $bolRtn;
    }

    public function delUploadImageBySQId($intSQId) {
        $bolRtn = true;
        //檢查上傳圖檔編號是否為空白
        if (empty ($intSQId)) {
            throw new Exception('缺少子題編號，無法刪除上傳圖檔。');
        }

        //取得資料庫裡儲存的圖片記錄
        $aryAllSQImg = $this->getAllSQUploadImgBySQId($intSQId);

        foreach($aryAllSQImg as $rowAllSQImg) {
            $bolRtn = $bolRtn && $this->delUploadImageByULId($rowAllSQImg[0]);
        }   //End foreach

        return $bolRtn;

    }

    function  __destruct() {
        if ($this->rsStrImagePic != null) {
            imagedestroy($this->rsStrImagePic);
        }
        if ($this->rsDestImagePic != null) {
            imagedestroy($this->rsDestImagePic);
        }

        if ($this->mysqli) {
            $this->mysqli->close();
            $this->mysqli = FALSE;
        }
    }
}
?>
